package com.tengju.bff.interfaces.covercharge.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beust.jcommander.internal.Lists;
import com.idanchuang.component.redis.util.DRedisLocks;
import com.tengju.bff.interfaces.covercharge.constant.*;
import com.tengju.bff.interfaces.covercharge.entity.dto.WithdrawalCancelInternal;
import com.tengju.bff.interfaces.covercharge.entity.po.*;
import com.tengju.bff.interfaces.covercharge.entity.vo.SelfCertificationQuery;
import com.tengju.bff.interfaces.covercharge.entity.vo.ServiceSignQuery;
import com.tengju.bff.interfaces.covercharge.entity.vo.ServiceSignRecordVo;
import com.tengju.bff.interfaces.covercharge.entity.vo.contract.SignContractReqVo;
import com.tengju.bff.interfaces.covercharge.handler.CoverChargeException;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceSignMapper;
import com.tengju.bff.interfaces.covercharge.service.*;
import com.tengju.bff.interfaces.covercharge.util.BeanMapperUtils;
import com.tengju.bff.interfaces.covercharge.util.UserUtils;
import com.tengju.bff.interfaces.shared.ApiResponse;
import com.tengju.settlement.application.shared.ApplicationException;
import com.tengju.settlement.application.shared.ApplicationExceptionCode;
import com.tengju.settlement.domain.model.depository.*;
import com.tengju.user.application.sms.SmsBizService;
import com.tengju.user.domain.model.archive.sign.SignFromEnum;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.service.UserDocService;
import com.zoi7.component.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务费经销商签约表 服务实现类
 * </p>
 *
 * @author fwy
 * @since 2020-03-04
 */
@Service
@Slf4j
public class ServiceSignServiceImpl extends ServiceImpl<ServiceSignMapper, ServiceSign> implements IServiceSignService {

    @Resource
    private IServiceSelfCertificationWithdrawService serviceSelfCertificationWithdrawService;
    @Resource
    private IServiceSelfCertificationService serviceSelfCertificationService;
    @Resource
    private IServiceLetaxRegisteredService serviceLetaxRegisteredService;
    @Resource
    private IServiceLetaxWithdrawLogService serviceLetaxWithdrawLogService;
    @Resource
    @Lazy
    private LeTaxOneServiceImpl leTaxOneService;
    @Resource
    private IServiceSignLogService serviceSignLogService;
    @Resource
    @Lazy
    private ServiceSignServiceImpl serviceSignService;
    @Resource
    private UserInfoRepository userInfoRepository;
    @Resource
    private UserDocService userDocService;
    @Autowired
    private SmsBizService smsBizService;
    @Autowired
    private UserService userService;
    @Autowired
    private IAttachmentService attachmentService;
    @Autowired
    private SelfCertificationService selfCertificationService;
    @Autowired
    private IServiceContractService serviceContractService;
    @Autowired
    @Lazy
    private SelfCertificationServiceImpl selfCertificationServiceImpl;
    @Autowired
    private IServiceSignRecordService serviceSignRecordService;
    @Autowired
    private DepositoryAccountRepository depositoryAccountRepository;
    @Autowired
    private DepositoryBankCardRepository depositoryBankCardRepository;


    @Value("${depository.account.whiteList}")
    private String DepAccountWhiteList;

    /**
     * 签约记录页面
     *
     * @param page
     * @param signingTime
     * @param idCode
     * @param mobile
     * @param userName
     * @param platformCode
     * @param signName
     * @param idNumberIdNumber
     * @param status
     * @param subStatus
     * @param methodCooperation
     * @return
     */
    @Override
    public Page<ServiceSignQuery> queryByPage(Page page, @Param("signingTime") String signingTime,
                                              @Param("idCode") String idCode, @Param("mobile") String mobile, @Param("userName") String userName,
                                              @Param("platformCode") String platformCode, @Param("signName") String signName,
                                              @Param("idNumberIdNumber") String idNumberIdNumber, @Param("status") String status,
                                              @Param("subStatus") String subStatus, @Param("methodCooperation") String methodCooperation) {
        try {
            String signingTimeStart = "";
            String signingTimeEnd = "";
            if (signingTime != null && !"".equals(signingTime)) {
                signingTimeStart = signingTime + " 00:00:00";
                signingTimeEnd = signingTime + " 23:59:59";
            }
            String subStatusIsCe = "";
            if (SignIdentityEnum.certified_business.toString().equals(methodCooperation) || SignIdentityEnum.certified_individual.toString().equals(methodCooperation)) {
                subStatusIsCe = "ce";
            }

            if (!StringUtils.isBlank(mobile)) {
                try {
                    UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(null, mobile);
                    if (userInfo == null) {
                        return new Page<>();
                    }
                    idCode = String.valueOf(Integer.parseInt(userInfo.getIdCode() + ""));
                } catch (Exception e) {
                    log.error("UBaseResult信息获取失败：", e);
                    throw new ServiceException(e.getMessage());
                }
            }
            Integer toTal = this.baseMapper.queryTotal(signingTimeStart, signingTimeEnd, idCode, mobile, userName, platformCode, signName,
                    idNumberIdNumber, status, subStatus, subStatusIsCe, methodCooperation);
            page.setSearchCount(false);
            page.setOptimizeCountSql(false);
            page.setTotal(toTal);

            List<ServiceSignQuery> list = this.baseMapper.queryByPage(page, signingTimeStart, signingTimeEnd, idCode, mobile, userName, platformCode, signName,
                    idNumberIdNumber, status, subStatus, subStatusIsCe, methodCooperation);
            List<UserIdCode> idList = new ArrayList<>();
            for (ServiceSignQuery serviceSignQuery : list) {
                idList.add(new UserIdCode(serviceSignQuery.getIdCode()));
            }

            Map<UserIdCode, UserInfo> userMap = userService.queryUserMap(idList);
//            List<DepositoryBankCard> bankCards = depositoryBankCardRepository
//                    .getByIdCodesStatus(idList.stream().map(UserIdCode::getValue)
//                                    .map(com.tengju.settlement.domain.model.account.UserIdCode::new).collect(Collectors.toList()),
//                            List.of(BindStatus.SUCCESS));
//            Map<UserIdCode, DepositoryBankCard> bankCardMap = bankCards.stream()
//                    .collect(Collectors.toMap(depositoryBankCard -> new UserIdCode(depositoryBankCard.getIdCode().getValue()),
//                            Function.identity()));

            List<UserIdCode> whiteIdCodeList = Lists.newArrayList();
            if (!StringUtils.isEmpty(DepAccountWhiteList)) {
                whiteIdCodeList = Arrays.stream(DepAccountWhiteList.split(","))
                        .map(Long::parseLong)
                        .map(UserIdCode::new)
                        .collect(Collectors.toList());
            }



            List<DepositoryAccount> pingAnDepositoryAccounts = depositoryAccountRepository.getByIdCodesStatusNormal(idList.stream().map(UserIdCode::getValue)
                    .map(com.tengju.settlement.domain.model.account.UserIdCode::new).collect(Collectors.toList()),DepositoryChannel.PING_AN);
            List<DepositoryAccountId> pingAnDepositoryAccountIds = pingAnDepositoryAccounts
                    .stream().map(DepositoryAccount::getDepositoryAccountId).collect(Collectors.toList());
            List<DepositoryAccount> internalDepositoryAccounts = depositoryAccountRepository.getByIdCodesStatusNormal(idList.stream().map(UserIdCode::getValue)
                    .map(com.tengju.settlement.domain.model.account.UserIdCode::new).collect(Collectors.toList()),DepositoryChannel.INTERNAL);
            List<DepositoryAccountId> internalDepositoryAccountIds = internalDepositoryAccounts
                    .stream().map(DepositoryAccount::getDepositoryAccountId).collect(Collectors.toList());

            Map<UserIdCode, DepositoryBankCard> pingAnDepositoryBankCardMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(pingAnDepositoryAccountIds)) {
                List<DepositoryBankCard> pingAnDepositoryBankCards = depositoryBankCardRepository
                        .getByDepositoryAccountIdsStatus(pingAnDepositoryAccountIds, List.of(BindStatus.SUCCESS));
                pingAnDepositoryBankCardMap = pingAnDepositoryBankCards.stream()
                        .collect(Collectors.toMap(depositoryBankCard -> new UserIdCode(depositoryBankCard.getIdCode().getValue()), Function.identity()));
            }

            Map<UserIdCode, DepositoryBankCard> internalDepositoryBankCardMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(internalDepositoryAccountIds)) {
                List<DepositoryBankCard> internalDepositoryBankCards = depositoryBankCardRepository
                        .getByDepositoryAccountIdsStatus(internalDepositoryAccountIds, List.of(BindStatus.SUCCESS));
                internalDepositoryBankCardMap = internalDepositoryBankCards.stream()
                        .collect(Collectors.toMap(depositoryBankCard -> new UserIdCode(depositoryBankCard.getIdCode().getValue()), Function.identity()));
            }

            for (ServiceSignQuery serviceSignQuery : list) {

                boolean hitWhiteList = false;
                if (!org.springframework.util.StringUtils.isEmpty(DepAccountWhiteList)) {
                    hitWhiteList = whiteIdCodeList.contains(new UserIdCode(serviceSignQuery.getIdCode()));
                }
                DepositoryBankCard depositoryBankCard;
                if (hitWhiteList) {
                    depositoryBankCard = internalDepositoryBankCardMap.get(new UserIdCode(serviceSignQuery.getIdCode()));
                } else {
                    depositoryBankCard = pingAnDepositoryBankCardMap.get(new UserIdCode(serviceSignQuery.getIdCode()));
                }


                serviceSignQuery.setPaymentAccount(Optional.ofNullable(depositoryBankCard).map(DepositoryBankCard::getCardNo).orElse(""));
                serviceSignQuery.setCeBankName(Optional.ofNullable(depositoryBankCard).map(DepositoryBankCard::getBankName).orElse(""));

                Integer userId = UserUtils.getUserId(serviceSignQuery.getIdCode());
                if (!StringUtils.isBlank(serviceSignQuery.getLicenceImg())) {
                    //查询图片
                    String url = attachmentService.getUrl(serviceSignQuery.getLicenceImg());
                    if (StringUtils.isNotBlank(url)) {
                        serviceSignQuery.setLicenceImg(url);
                    }
                }

                if (!StringUtils.isBlank(serviceSignQuery.getBusinessImg())) {
                    //查询图片
                    String url = attachmentService.getUrl(serviceSignQuery.getBusinessImg());
                    if (StringUtils.isNotBlank(url)) {
                        serviceSignQuery.setBusinessImg(url);
                    }
                }
                if (userMap.containsKey(new UserIdCode(serviceSignQuery.getIdCode()))) {
                    UserInfo userVO = userMap.get(new UserIdCode(serviceSignQuery.getIdCode()));
                    serviceSignQuery.setMobile(userVO.getMobile());
                    serviceSignQuery.setName(userVO.getName());
                }

                if (StringUtils.isNotBlank(serviceSignQuery.getIdCardType())) {
                    serviceSignQuery.setIdCardTypeName(IdentityTypeEnum.get(serviceSignQuery.getIdCardType()).getMsg());
                }

                //如果有星际区域服务商签约记录，并是乐税和自认证身份，查询是否需要申请数字证书
                ServiceSignRecordVo serviceSignRecord = serviceSignRecordService.queryFirst(serviceSignQuery.getId(),
                        SignFromEnum.SERVICE_PROVIDER.getCode());
                if (Objects.nonNull(serviceSignRecord) && (LetaxRegisteredStatusEnum.REGISTRATION_COMPLET.getCode().toString().equals(serviceSignQuery.getSubStatus()) || SelfCertificationStatus.PASS.getCode().toString().equals(serviceSignQuery.getSubStatus())) && (serviceSignQuery.getCurrentIdentity().equals(SignIdentityEnum.regist_soho.getCode()) || serviceSignQuery.getCurrentIdentity().equals(SignIdentityEnum.certified_individual.getCode()) || serviceSignQuery.getCurrentIdentity().equals(SignIdentityEnum.certified_business.getCode()))) {
                    SignContractReqVo signContractReqVo = new SignContractReqVo();
                    Integer type;
                    if (serviceSignQuery.getCurrentIdentity().equals(SignIdentityEnum.regist_soho.getCode())) {
                        type = ContractFromEnum.LE_TAX_INDIVIDUAL.getFrom();
                    } else if (serviceSignQuery.getCurrentIdentity().equals(SignIdentityEnum.certified_individual.getCode())) {
                        type = ContractFromEnum.SELF_CERT_INDIVIDUAL.getFrom();
                    } else {
                        type = ContractFromEnum.SELF_CERT_COMPANY.getFrom();
                    }
                    signContractReqVo.setType(type);

                    //判断用户证书是否需要申请证,默认为否
                    serviceSignQuery.setIsApplyCertificate(IsSendEnum.SERVICE_FEE.getCode());
                    if (!serviceContractService.checkCert(serviceSignQuery.getPlatformCode(), serviceSignQuery.getIdCode(),
                            signContractReqVo, serviceSignQuery.getIdCardNo(), serviceSignQuery.getIdNumberIdNumber(), Boolean.FALSE)) {
                        serviceSignQuery.setIsApplyCertificate(IsSendEnum.TO_SIGN.getCode());
                    }
                }
            }
            page.setRecords(list);
            return page;
        } catch (Exception e) {
            log.error("管理签约记录表查询异常:", e);
            throw new ServiceException("查询失败");
        }
    }

    /**
     * 签约记录页面
     *
     * @param signingTime
     * @param idCode
     * @param mobile
     * @param userName
     * @param platformCode
     * @param signName
     * @param idNumberIdNumber
     * @param status
     * @param subStatus
     * @param methodCooperation
     * @return
     */
    @Override
    public List<ServiceSignQuery> queryByPageExport(@Param("signingTime") String signingTime,
                                                    @Param("idCode") String idCode, @Param("mobile") String mobile, @Param("userName") String userName,
                                                    @Param("platformCode") String platformCode, @Param("signName") String signName,
                                                    @Param("idNumberIdNumber") String idNumberIdNumber, @Param("status") String status,
                                                    @Param("subStatus") String subStatus, @Param("methodCooperation") String methodCooperation) {

        String signingTimeStart = "";
        String signingTimeEnd = "";
        if (signingTime != null && !"".equals(signingTime)) {
            signingTimeStart = signingTime + " 00:00:00";
            signingTimeEnd = signingTime + " 23:59:59";
        }
        String subStatusIsCe = "";
        if (methodCooperation.equals(SignIdentityEnum.certified_business.toString()) || methodCooperation.equals(SignIdentityEnum.certified_individual.toString())) {
            subStatusIsCe = "ce";
        }

        if (StringUtils.isNotEmpty(mobile)) {
            try {
                UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(null, mobile);
                if (userInfo == null) {
                    return Lists.newArrayList();
                }
                idCode = String.valueOf(Integer.parseInt(userInfo.getIdCode() + ""));
            } catch (Exception e) {
                throw new ServiceException(e.getMessage());
            }
        }
        List<ServiceSignQuery> list = this.baseMapper.queryByPageExport(signingTimeStart, signingTimeEnd, idCode, mobile, userName, platformCode, signName,
                idNumberIdNumber, status, subStatus, subStatusIsCe, methodCooperation);
        List<UserIdCode> idList = list.stream()
                .map(s -> new UserIdCode(s.getIdCode()))
                .collect(Collectors.toList());
        Map<UserIdCode, UserInfo> userMap = userService.queryUserMap(idList);

        for (ServiceSignQuery serviceSignQuery : list) {
            UserIdCode userIdCode = new UserIdCode(serviceSignQuery.getIdCode());

            if (userMap.containsKey(userIdCode)) {
                UserInfo userVO = userMap.get(userIdCode);
                serviceSignQuery.setMobile(userVO.getMobile());
                serviceSignQuery.setName(userVO.getName());
            }

            serviceSignQuery.setSubStatus(getSubStatusName(serviceSignQuery));
            if (serviceSignQuery.getCurrentIdentity() == null || "".equals(serviceSignQuery.getCurrentIdentity())) {
                serviceSignQuery.setCurrentIdentity("");
            } else {
                if (SignIdentityEnum.getStatusDesc(serviceSignQuery.getCurrentIdentity()) != null) {
                    serviceSignQuery.setCurrentIdentity(SignIdentityEnum.getStatusDesc(serviceSignQuery.getCurrentIdentity()).getDesc());
                }
            }
            if (serviceSignQuery.getIsSigned() == null || "".equals(serviceSignQuery.getIsSigned())) {
                serviceSignQuery.setCurrentIdentity("");
            } else {
                if (IsSigndEnum.getStatusDesc(serviceSignQuery.getIsSigned()) != null) {
                    serviceSignQuery.setIsSigned(IsSigndEnum.getStatusDesc(serviceSignQuery.getIsSigned()).getDesc());
                }
            }
        }


        return list;
    }

    private String getSubStatusName(ServiceSignQuery serviceSignQuery) {
        if (serviceSignQuery.getSubStatus() == null || "".equals(serviceSignQuery.getSubStatus())) {
            return "";
        }
        if (SignIdentityEnum.no_identity.toString().equals(serviceSignQuery.getCurrentIdentity())) {
            return "";
        }
        if (SignIdentityEnum.person.toString().equals(serviceSignQuery.getCurrentIdentity())) {
            return "";
        }
        if (SignIdentityEnum.regist_soho.toString().equals(serviceSignQuery.getCurrentIdentity())) {
            LetaxRegisteredStatusEnum statusEnum = LetaxRegisteredStatusEnum.getStatusDesc(Integer.valueOf(serviceSignQuery.getSubStatus()));
            return Objects.isNull(statusEnum) ? null : statusEnum.getDesc();
        }
        if (SignIdentityEnum.certified_individual.toString().equals(serviceSignQuery.getCurrentIdentity())) {
            SelfCertificationStatus scsEnum = SelfCertificationStatus.getStatusDesc(Integer.valueOf(serviceSignQuery.getSubStatus()));
            return Objects.isNull(scsEnum) ? null : scsEnum.getDescriptioin();
        }
        if (SignIdentityEnum.certified_business.toString().equals(serviceSignQuery.getCurrentIdentity())) {
            SelfCertificationStatus scsEnum = SelfCertificationStatus.getStatusDesc(Integer.valueOf(serviceSignQuery.getSubStatus()));
            return Objects.isNull(scsEnum) ? null : scsEnum.getDescriptioin();
        }
        return "";
    }

    /**
     * 签约终止
     *
     * @param id
     * @param adminId
     * @return JsonResult
     */
    @Override
    public ApiResponse<Object> terminateSign(Integer id, Integer adminId) {
        ServiceSignQuery signData = this.baseMapper.queryOnce(id);
        if (signData == null) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "无此条目");
        }

        //存管账户开户校验
        List<DepositoryAccount> depositoryAccount = depositoryAccountRepository
                .getByIdCodeStatus(new com.tengju.settlement.domain.model.account.UserIdCode(signData.getIdCode()),
                        List.of(AccountStatus.NORMAL, AccountStatus.LOGICAL_CANCEL, AccountStatus.CARD_NOT_BIND, AccountStatus.CARD_BINDING), DepositoryChannel.PING_AN);
        if (!CollectionUtils.isEmpty(depositoryAccount)) {
            throw ApplicationException.error(ApplicationExceptionCode.TERMINATE_FAIL_DEP_ACCOUNT_OPENED);
        }

        boolean isCertified = SignIdentityEnum.certified_individual.toString().equals(signData.getCurrentIdentity())
                || SignIdentityEnum.certified_business.toString().equals(signData.getCurrentIdentity());

        if (isCertified && IsSigndEnum.No.toString().equals(signData.getIsSigned()) && SelfCertificationStatus.WAITING_APPROVED.getCode().toString().equals(signData.getSubStatus())) {

            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "不允许进行终止操作!");
        }

        return DRedisLocks.runWithLock(BizConstants.TERMINATION_THE_CONTRACT + signData.getIdCode(), 500, () -> {
            try {
                return serviceSignService.performTerminateSign(adminId, signData);
            } catch (Exception e) {
                return ApiResponse.newFailure(CoverChargeErrorCode.SYS_ERROR.getCode(), e.getMessage());
            }
        });


    }

    /**
     * 签约终止
     *
     * @param adminId
     * @param signData
     * @return JsonResult
     */
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Object> performTerminateSign(Integer adminId, ServiceSignQuery signData) {
        AtomicReference<ApiResponse<Object>> stopSingResult = new AtomicReference<>(ApiResponse.newSuccess());
        //个人签约终止

        //乐税注册个体户终止
        if (SignIdentityEnum.regist_soho.toString().equals(signData.getCurrentIdentity())) {
            QueryWrapper<ServiceLetaxRegistered> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("platform_code", signData.getPlatformCode());
            queryWrapper.eq("id_code", signData.getIdCode());
            queryWrapper.ne("status", LetaxRegisteredStatusEnum.TERMINATION_OF.getCode());
            ServiceLetaxRegistered serviceLetaxRegisteredInfo = serviceLetaxRegisteredService.getOne(queryWrapper);
            if (serviceLetaxRegisteredInfo == null) {
                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "没有乐税认证记录");
            }

            stopSingResult.set(stopLex(signData, serviceLetaxRegisteredInfo));

            if (!stopSingResult.get().isSuccess()) {
                return stopSingResult.get();
            }
        }

        //自认证（个体 企业）终止
        if (SignIdentityEnum.certified_individual.toString().equals(signData.getCurrentIdentity())
                || SignIdentityEnum.certified_business.toString().equals(signData.getCurrentIdentity())) {
            if (IsSigndEnum.No.toString().equals(signData.getIsSigned()) && SelfCertificationStatus.WAITING_APPROVED
                    .getCode().toString().equals(signData.getSubStatus())) {

                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "不允许进行终止操作!");
            }
            QueryWrapper<ServiceSelfCertification> serviceSelfCertificationQueryWrapper = new QueryWrapper<>();
            serviceSelfCertificationQueryWrapper.eq("platform_code", signData.getPlatformCode());
            serviceSelfCertificationQueryWrapper.eq("id_code", signData.getIdCode());
            serviceSelfCertificationQueryWrapper.ne("status", SelfCertificationStatus.STOP.getCode());
            ServiceSelfCertification serviceSelfCertificationInfo = serviceSelfCertificationService
                    .getOne(serviceSelfCertificationQueryWrapper);

            if (serviceSelfCertificationInfo == null) {
                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "没有这条签约记录!");
            }

            stopSingResult.set(singleStopSelfCertification(serviceSelfCertificationInfo, adminId));

            if (!stopSingResult.get().isSuccess()) {
                return stopSingResult.get();
            }
        }

        //个人终止
        if (SignIdentityEnum.person.toString().equals(signData.getCurrentIdentity())) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "请引导个人签约用户自行解绑,无法后台操作");
        }

        //更新签约记录表
        serviceSignRecordService.updateStatus(signData.getId(), SignFromEnum.SERVICE_PROVIDER.getCode());

        //更新签约记录表
        this.baseMapper.terminate(signData.getId(), signData.getCurrentIdentity());
        //新增签约变更记录日志
        ServiceSignLog serviceSignLog = new ServiceSignLog();
        serviceSignLog.setBeforeIdentity(signData.getCurrentIdentity());
        serviceSignLog.setLastIdentity(SignIdentityEnum.no_identity.toString());
        serviceSignLog.setCreatedBy(adminId.toString());
        serviceSignLog.setCreatedTime(LocalDateTime.now());
        serviceSignLog.setIdCode(signData.getIdCode());
        serviceSignLog.setOperateType("终止");
        serviceSignLog.setPlatformCode(signData.getPlatformCode());
        serviceSignLogService.save(serviceSignLog);
        return stopSingResult.get();
    }


    /**
     * 审核通过
     *
     * @param id
     * @param adminId
     * @return JsonResult
     */
    @Override
    public ApiResponse<Object> approv(Integer id, Integer adminId) {
        ServiceSignQuery serviceSignData = this.baseMapper.queryOnce(id);
        if (serviceSignData == null) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "无此条目");
        }
        //只有认证 已签约 待审核状态下才能审核通过
        if (!(SignIdentityEnum.certified_individual.toString().equals(serviceSignData.getCurrentIdentity())
                || SignIdentityEnum.certified_business.toString().equals(serviceSignData.getCurrentIdentity()))) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "当前必须为认证用户");
        }
        if (IsSigndEnum.No.toString().equals(serviceSignData.getIsSigned())) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "用户尚未签约，不可执行审核通过操作");
        }

        ApiResponse<Object> result = DRedisLocks.runWithLock(BizConstants.CERTIFICATION_AUDIT_BY_SIGN + serviceSignData.getIdCode(), 500, () -> {
            try {
                return serviceSignService.performApprov(adminId, serviceSignData);
            } catch (Exception e) {
                return ApiResponse.newFailure(CoverChargeErrorCode.SYS_ERROR.getCode(), e.getMessage());
            }
        });
//        if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(serviceSignData.getPlatformCode())) {
//            if (result.isSuccess()) {
//                String methodCooperation = "【企业】";
//                if (SignIdentityEnum.certified_individual.toString().equals(serviceSignData.getCurrentIdentity())) {
//                    methodCooperation = "【个体工商户】";
//                }
//
////                userMessageClient.sendDtServiceFeeMessage(serviceSignData.getIdCode(), "服务费签约通知",
////                        "您已完成" + methodCooperation + "的合作方式签约，请查看合作方式说明，了解更多详情",
////                        true, true, false);
//            }
//        }


        return result;

    }

    /**
     * 审核通过处理
     *
     * @param adminId
     * @param serviceSignData
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Object> performApprov(Integer adminId, ServiceSignQuery serviceSignData) {
        Integer canceNum = 0;
        //获取自认证记录
        QueryWrapper<ServiceSelfCertification> serviceSelfCertificationInfoQueryWrapper = new QueryWrapper<>();
        serviceSelfCertificationInfoQueryWrapper.eq("platform_code", serviceSignData.getPlatformCode());
        serviceSelfCertificationInfoQueryWrapper.eq("id_code", serviceSignData.getIdCode());
        serviceSelfCertificationInfoQueryWrapper.eq("status", 0);
        ServiceSelfCertification serviceSelfCertificationInfo = serviceSelfCertificationService
                .getOne(serviceSelfCertificationInfoQueryWrapper);
        if (serviceSelfCertificationInfo == null) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "不存在的认证记录!");
        }
        LocalDateTime nowTime = LocalDateTime.now();

        //个人升级到认证
        if (StringUtils.equals(SignIdentityEnum.person.toString(), serviceSignData.getBeforeIdentity())) {
            //取消提现记录
            WithdrawalCancelInternal withdrawalCancel = new WithdrawalCancelInternal();
            withdrawalCancel.setCurrentIdentity(serviceSignData.getCurrentIdentity());
            withdrawalCancel.setPlatformCode(serviceSignData.getPlatformCode());
            withdrawalCancel.setIdCode(serviceSignData.getIdCode());
            canceNum = this.cancelWithdrawalApply(withdrawalCancel);
        }
        //注册到认证
        if (SignIdentityEnum.regist_soho.toString().equals(serviceSignData.getBeforeIdentity())) {
            //取消周期内提现
            WithdrawalCancelInternal withdrawalCancel = new WithdrawalCancelInternal();
            withdrawalCancel.setCurrentIdentity(serviceSignData.getBeforeIdentity());
            withdrawalCancel.setPlatformCode(serviceSignData.getPlatformCode());
            withdrawalCancel.setIdCode(serviceSignData.getIdCode());
            canceNum = this.cancelWithdrawalApply(withdrawalCancel);
        }

//        if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(serviceSignData.getPlatformCode())) {
//            String methodCooperation = "【企业】";
//            if (SignIdentityEnum.certified_individual.toString().equals(serviceSignData.getCurrentIdentity())) {
//                methodCooperation = "【个体工商户】";
//            }
//            if (canceNum != 0) {
//                String content = "您的合作方式已升级为" + methodCooperation + "，您有" + canceNum + "笔服务费申请已自动取消，请通过新的合作方式重新发起申请。";
////                userMessageClient.sendDtServiceFeeMessage(serviceSignData.getIdCode(), "服务费申请通知", content,
////                        true, true, false);
//                smsBizService.sendAccountChangeMode(userInfo.getMobile(),methodCooperation,canceNum);
////                userMessageClient.sendMobileMessage(serviceSignData.getIdCode(), content);
//            }
//        }


        //修改企业认证记录为通过
        serviceSelfCertificationInfo.setAdminId(adminId);
        serviceSelfCertificationInfo.setStatus(SelfCertificationStatus.PASS.getCode());
        serviceSelfCertificationInfo.setCheckAt(nowTime);
        serviceSelfCertificationInfo.setUpdatedAt(nowTime);
        serviceSelfCertificationService.updateById(serviceSelfCertificationInfo);

        //新增签约变更记录日志
        ServiceSignLog serviceSignLog = new ServiceSignLog();
        serviceSignLog.setBeforeIdentity(serviceSignData.getCurrentIdentity());
        serviceSignLog.setLastIdentity(serviceSignData.getCurrentIdentity());
        serviceSignLog.setCreatedBy(adminId.toString());
        serviceSignLog.setCreatedTime(nowTime);
        serviceSignLog.setIdCode(serviceSignData.getIdCode());
        serviceSignLog.setOperateType("认证签约审核通过");
        serviceSignLog.setPlatformCode(serviceSignData.getPlatformCode());
        serviceSignLogService.save(serviceSignLog);

        //是否去通知会员和申请数字证书
        //ServiceSignRecordVo serviceSignRecord =serviceSignRecordService.queryFirst(serviceSignData.getId(),SignFromEnum.SERVICE_PROVIDER.getCode());
        //if(Objects.nonNull(serviceSignRecord)){
        try {
            //拼接参数
            SelfCertificationQuery selfCertificationQuery = new SelfCertificationQuery();
            selfCertificationQuery.setIdCode(serviceSignData.getIdCode());
            selfCertificationQuery.setPlatformCode(serviceSignData.getPlatformCode());
            selfCertificationQuery.setCheckAt(nowTime);
            selfCertificationQuery.setBeforeIdentity(serviceSignData.getBeforeIdentity());
            selfCertificationQuery.setCurrentIdentity(serviceSignData.getCurrentIdentity());
            if (serviceSignData.getCurrentIdentity().equals(SignIdentityEnum.regist_soho.getCode())) {
                selfCertificationQuery.setType(ContractFromEnum.LE_TAX_INDIVIDUAL.getFrom());
            } else if (serviceSignData.getCurrentIdentity().equals(SignIdentityEnum.certified_business.getCode())) {
                selfCertificationQuery.setType(ContractFromEnum.SELF_CERT_COMPANY.getFrom());
            } else {
                selfCertificationQuery.setType(ContractFromEnum.SELF_CERT_INDIVIDUAL.getFrom());
            }

            //拼接申请数字证书参数
            selfCertificationQuery.setType(serviceSelfCertificationInfo.getType());
            selfCertificationQuery.setPlatformCode(serviceSelfCertificationInfo.getPlatformCode());
            selfCertificationQuery.setIdcardType(serviceSelfCertificationInfo.getIdcardType());
            selfCertificationQuery.setIdcardNo(serviceSelfCertificationInfo.getIdcardNo());
            selfCertificationQuery.setIdcardName(serviceSelfCertificationInfo.getIdcardName());
            selfCertificationQuery.setCompanyNo(serviceSelfCertificationInfo.getCompanyNo());
            selfCertificationQuery.setCompanyName(serviceSelfCertificationInfo.getCompanyName());
            selfCertificationQuery.setLegalMobile(serviceSelfCertificationInfo.getLegalMobile());

            //包含法人信息才去生成数字和通知会员
            if (StringUtils.isNotBlank(selfCertificationQuery.getIdcardNo())
                    && StringUtils.isNotBlank(selfCertificationQuery.getIdcardName())
                    && StringUtils.isNotBlank(selfCertificationQuery.getCompanyNo())
                    && StringUtils.isNotBlank(selfCertificationQuery.getCompanyName())
                    && StringUtils.isNotBlank(selfCertificationQuery.getLegalMobile())) {
                //生成数字证书
                selfCertificationServiceImpl.registeredApplyCert(selfCertificationQuery);

                //数字证书成功后且签约记录有效才去通知会员
                //if(serviceSignRecord.getStatus().equals(SignRecordStatusEnum.VALID.getCode())){
                selfCertificationService.noticeStarService(selfCertificationQuery);
                //}
            }

        } catch (CoverChargeException ce) {
            throw new ServiceException(ce.getMsg());
        } catch (Exception e) {
            log.error("申请证书或者通知会员报错", e);
            throw new ServiceException("申请证书或者通知会员失败");
        }
        //}

        return ApiResponse.newSuccess();
    }


    /**
     * 功能描述: <br>
     * 审核成功取消个人和乐税服务费提现申请
     *
     * @param withdrawalCancel 提现申请取消
     */
    private Integer cancelWithdrawalApply(@RequestBody WithdrawalCancelInternal withdrawalCancel) {
        log.info("后台操作审核成功自认证，取消服务费提现申请...{}", JSON.toJSONString(withdrawalCancel));
        Assert.notNull(withdrawalCancel.getIdCode(), "idCode不能为空");
        Assert.hasText(withdrawalCancel.getPlatformCode(), "平台编号不能为空");
        Assert.isTrue(
                CoverChargeEnum.ServiceAccountType.MANAGE_TYPE.getPlatform().equals(withdrawalCancel.getPlatformCode()), "平台编号不正确");

        Assert.hasText(withdrawalCancel.getCurrentIdentity(), "当前身份不能为空");
        int num = 0;
        try {
            num = leTaxOneService.withdrawalApplyCancelNoTran(withdrawalCancel.getIdCode(),
                    withdrawalCancel.getPlatformCode(), null, WithdrawalCancelEnum.upgrade);
        } catch (Exception e) {
            log.error("withdrawalApplyCancelNoTran", e);
        }

        return num;
    }

    /**
     * 审核拒绝
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResponse<Object> auditRefusedTo(Integer id, Integer adminId, String remark) {
        ServiceSignQuery serviceSignData = this.baseMapper.queryOnce(id);
        if (serviceSignData == null) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "无此条目");
        }
        //只有认证 已签约 待审核状态下才能审核拒绝
        if (!(SignIdentityEnum.certified_individual.toString().equals(serviceSignData.getCurrentIdentity())
                || SignIdentityEnum.certified_business.toString().equals(serviceSignData.getCurrentIdentity()))) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "当前必须为认证用户");
        }
        if (IsSigndEnum.No.toString().equals(serviceSignData.getIsSigned())) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "用户尚未签约，不可执行审核通过操作");
        }

        return DRedisLocks.runWithLock(BizConstants.CERTIFICATION_AUDIT_BY_SIGN + serviceSignData.getIdCode(), 500, () -> {
            try {
                return serviceSignService.performAuditRefusedTo(adminId, serviceSignData, remark);
            } catch (Exception e) {
                log.error("performAuditRefusedTo error", e);
                return ApiResponse.newFailure(CoverChargeErrorCode.SYS_ERROR.getCode(), e.getMessage());
            }
        });
    }

    /**
     * 审核拒绝
     *
     * @param adminId
     * @param serviceSignData
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Object> performAuditRefusedTo(Integer adminId, ServiceSignQuery serviceSignData, String remark) {
        //获取自认证记录
        ServiceSelfCertification serviceSelfCertificationWhere = new ServiceSelfCertification();
        serviceSelfCertificationWhere.setStatus(SelfCertificationStatus.WAITING_APPROVED.getCode());
        serviceSelfCertificationWhere.setIdCode(serviceSignData.getIdCode());
        serviceSelfCertificationWhere.setPlatformCode(serviceSignData.getPlatformCode());
        ServiceSelfCertification serviceSelfCertificationInfo = serviceSelfCertificationService
                .getOne(new QueryWrapper<>(serviceSelfCertificationWhere));
        if (serviceSelfCertificationInfo == null) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "不存在的认证记录!");
        }
        serviceSelfCertificationInfo.setAdminId(adminId);
        serviceSelfCertificationInfo.setStatus(SelfCertificationStatus.REFUSE.getCode());
        serviceSelfCertificationInfo.setRemark(remark);
        serviceSelfCertificationInfo.setCheckAt(LocalDateTime.now());
        serviceSelfCertificationInfo.setUpdatedAt(LocalDateTime.now());
        serviceSelfCertificationService.updateById(serviceSelfCertificationInfo);
        //新增签约变更记录日志
        ServiceSignLog serviceSignLog = new ServiceSignLog();
        serviceSignLog.setBeforeIdentity(serviceSignData.getBeforeIdentity());
        serviceSignLog.setLastIdentity(serviceSignData.getCurrentIdentity());
        serviceSignLog.setCreatedBy(adminId.toString());
        serviceSignLog.setCreatedTime(LocalDateTime.now());
        serviceSignLog.setIdCode(serviceSignData.getIdCode());
        serviceSignLog.setOperateType("后台审核拒绝");
        serviceSignLog.setPlatformCode(serviceSignData.getPlatformCode());
        serviceSignLogService.save(serviceSignLog);

        UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(serviceSignData.getIdCode()), null);
        //DT且来自星际才发短信
        ServiceSignRecordVo serviceSignRecord = serviceSignRecordService.queryFirst(serviceSignData.getId(), SignFromEnum.SERVICE_PROVIDER.getCode());
        if (Objects.nonNull(serviceSignRecord) && serviceSignRecord.getStatus().equals(SignRecordStatusEnum.VALID.getCode()) && serviceSignData.getPlatformCode().equals(PlatformCodeEnum.DT.getDescriptioin())) {
            String title = SelfCertificationTypeEnum.SINGLE.getDescriptioin();
            if (serviceSelfCertificationInfo.getType().equals(SelfCertificationTypeEnum.COMPANY.getCode())) {
                title = SelfCertificationTypeEnum.COMPANY.getDescriptioin();
            }
            String MessageContent = "抱歉，您的" + title + "认证审核失败，具体原因如下：" + remark + "。";
            Integer templateId = MessageTemplateIdEnum.DT.getCode();
            log.info("后台审核拒绝发送日志：{}", MessageContent);

            smsBizService.sendAccountAuthFail(userInfo.getMobile(), title, remark);
//            userMessageClient.sendMobileMessageByTemplate(serviceSignData.getIdCode(),templateId, MessageContent);
        }

        return ApiResponse.newSuccess();
    }

    /**
     * 认证个体户和认证企业终止
     *
     * @param serviceSelfCertification
     * @return JsonResult
     */
    private ApiResponse<Object> singleStopSelfCertification(ServiceSelfCertification serviceSelfCertification, Integer adminId) {
        if (SelfCertificationStatus.PASS.getCode().equals(serviceSelfCertification.getStatus())) {
            QueryWrapper<ServiceSelfCertificationWithdraw> withdrawalRecordNumberQueryWrapper = new QueryWrapper<>();
            withdrawalRecordNumberQueryWrapper.eq("self_certification_id", serviceSelfCertification.getId());
            Collection<Integer> statusIn = new ArrayList<>();
            statusIn.add(SelfWithdrawStatusEnum.CANCEL.getCode());
            statusIn.add(SelfWithdrawStatusEnum.SUCCESS.getCode());
            withdrawalRecordNumberQueryWrapper.notIn("status", statusIn);
            int serviceSelfCertificationWithdrawInfo = serviceSelfCertificationWithdrawService.count(withdrawalRecordNumberQueryWrapper);

            if (serviceSelfCertificationWithdrawInfo > 0) {
                return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "已经存在提现流程，不可终止,请取消后再操作");
            }
        }
        serviceSelfCertification.setStatus(SelfCertificationStatus.STOP.getCode());
        serviceSelfCertification.setAdminId(adminId);
        serviceSelfCertification.setUpdatedAt(LocalDateTime.now());
        serviceSelfCertificationService.updateById(serviceSelfCertification);

        return ApiResponse.newSuccess();
    }

    /**
     * 乐税终止
     *
     * @param signData
     * @param serviceLetaxRegisteredInfo
     * @return
     */
    private ApiResponse<Object> stopLex(ServiceSignQuery signData, ServiceLetaxRegistered serviceLetaxRegisteredInfo) {

        QueryWrapper<ServiceLetaxWithdrawLog> serviceLetaxWithdrawQueryWrapper = new QueryWrapper<>();
        serviceLetaxWithdrawQueryWrapper.eq("id_code", signData.getIdCode());
        serviceLetaxWithdrawQueryWrapper.eq("platform_code", signData.getPlatformCode());
        serviceLetaxWithdrawQueryWrapper.eq("auth_type", SignIdentityEnum.regist_soho.toString());
        Collection<Integer> statusIn = new ArrayList<>();
        statusIn.add(LetaxWithdrawStatusEnum.APPLY.getCode());
        statusIn.add(LetaxWithdrawStatusEnum.PASS.getCode());
        statusIn.add(LetaxWithdrawStatusEnum.PUTFAIL.getCode());
        statusIn.add(LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode());
        serviceLetaxWithdrawQueryWrapper.in("status", statusIn);
        int serviceLetaxWithdrawLogCount = serviceLetaxWithdrawLogService.count(serviceLetaxWithdrawQueryWrapper);
        if (serviceLetaxWithdrawLogCount > 0) {
            return ApiResponse.newFailure(CoverChargeErrorCode.BUSINESS_ERROR.getCode(), "已经存在提现流程，不可终止,请取消后再操作");
        }
        if (SignIdentityEnum.person.toString().equals(signData.getBeforeIdentity())) {
            leTaxOneService.withdrawalApplyCancelNoTran(signData.getIdCode(), signData.getPlatformCode(), null, WithdrawalCancelEnum.end);
        }
        serviceLetaxRegisteredInfo.setStatus(LetaxRegisteredStatusEnum.TERMINATION_OF.getCode());
        serviceLetaxRegisteredInfo.setUpdatedAt(LocalDateTime.now());
        serviceLetaxRegisteredService.updateById(serviceLetaxRegisteredInfo);

        return ApiResponse.newSuccess();
    }


    /**
     * 获取单条信息
     *
     * @param idCode
     * @param platformCode
     * @return
     */
    @Override
    public ServiceSignQuery queryFirst(Integer idCode, String platformCode) {
        ServiceSign sign = new ServiceSign();
        sign.setIdCode(idCode);
        sign.setPlatformCode(platformCode);
        ServiceSign signInfo = serviceSignService.getOne(new QueryWrapper<>(sign));
        if (Objects.isNull(signInfo)) {
            return null;
        }
        return BeanMapperUtils.map(signInfo, ServiceSignQuery.class);
    }
}
